home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
gnu
/
gdb
/
gdb_18s.zoo
/
valprint.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-03-25
|
18KB
|
679 lines
/* Print values for GNU debugger gdb.
Copyright (C) 1986, 1988 Free Software Foundation, Inc.
GDB is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY. No author or distributor accepts responsibility to anyone
for the consequences of using it or for whether it serves any
particular purpose or works at all, unless he says so in writing.
Refer to the GDB General Public License for full details.
Everyone is granted permission to copy, modify and redistribute GDB,
but only under the conditions described in the GDB General Public
License. A copy of this license is supposed to have been given to you
along with GDB so you can know your rights and responsibilities. It
should be in a file named COPYING. Among other things, the copyright
notice and this notice must be preserved on all copies.
In other words, go ahead and share GDB, but don't try to stop
anyone else from sharing it farther. Help stamp out software hoarding!
*/
#include <stdio.h>
#include "defs.h"
#include "symtab.h"
#include "value.h"
/* Maximum number of chars to print for a string pointer value
or vector contents. */
static int print_max;
static void type_print_varspec_suffix ();
static void type_print_varspec_prefix ();
static void type_print_base ();
char **unsigned_type_table;
char **signed_type_table;
char **float_type_table;
/* Print the value VAL in C-ish syntax on stream STREAM.
FORMAT is a format-letter, or 0 for print in natural format of data type.
If the object printed is a string pointer, returns
the number of string bytes printed. */
value_print (val, stream, format)
value val;
FILE *stream;
char format;
{
register int i, n, typelen;
if (val == 0)
{
printf_filtered ("<address of value unknown>");
return 0;
}
/* A "repeated" value really contains several values in a row.
They are made by the @ operator.
Print such values as if they were arrays. */
if (VALUE_REPEATED (val))
{
n = VALUE_REPETITIONS (val);
typelen = TYPE_LENGTH (VALUE_TYPE (val));
fputc_filtered ('{', stream);
/* Print arrays of characters using string syntax. */
if (typelen == 1 && TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_INT
&& format == 0)
{
fputc_filtered ('"', stream);
for (i = 0; i < n && i < print_max; i++)
{
QUIT;
printchar (VALUE_CONTENTS (val)[i], stream);
}
if (i < n)
fprintf_filtered (stream, "...");
fputc_filtered ('"', stream);
}
else
{
for (i = 0; i < n && i < print_max; i++)
{
if (i)
fprintf_filtered (stream, ", ");
val_print (VALUE_TYPE (val), VALUE_CONTENTS (val) + typelen * i,
VALUE_ADDRESS (val) + typelen * i, stream, format);
}
if (i < n)
fprintf_filtered (stream, "...");
}
fputc_filtered ('}', stream);
return n * typelen;
}
else
{
/* A simple (nonrepeated) value */
/* If it is a pointer, indicate what it points to. */
if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_PTR)
{
fprintf_filtered (stream, "(");
type_print (VALUE_TYPE (val), "", stream, -1);
fprintf_filtered (stream, ") ");
}
return val_print (VALUE_TYPE (val), VALUE_CONTENTS (val),
VALUE_ADDRESS (val), stream, format);
}
}
/* Print data of type TYPE located at VALADDR (within GDB),
which came from the inferior at address ADDRESS,
onto stdio stream STREAM according to FORMAT
(a letter or 0 for natural format).
If the data are a string pointer, returns the number of
sting characters printed. */
int
val_print (type, valaddr, address, stream, format)
struct type *type;
char *valaddr;
CORE_ADDR address;
FILE *stream;
char format;
{
register int i;
int len;
struct type *elttype;
int eltlen;
int val;
unsigned char c;
QUIT;
switch (TYPE_CODE (type))
{
case TYPE_CODE_ARRAY:
if (TYPE_LENGTH (type) >= 0)
{
elttype = TYPE_TARGET_TYPE (type);
eltlen = TYPE_LENGTH (elttype);
len = TYPE_LENGTH (type) / eltlen;
fprintf_filtered (stream, "{");
/* For an array of chars, print with string syntax. */
if (eltlen == 1 && TYPE_CODE (elttype) == TYPE_CODE_INT
&& format == 0)
{
fputc_filtered ('"', stream);
for (i = 0; i < len && i < print_max; i++)
{
QUIT;
printchar (valaddr[i], stream);
}
if (i < len)
fprintf_filtered (stream, "...");
fputc_filtered ('"', stream);
}
else
{
for (i = 0; i < len && i < print_max; i++)
{
if (i) fprintf_filtered (stream, ", ");
val_print (elttype, valaddr + i * eltlen,
0, stream, format);
}
if (i < len)
fprintf_filtered (stream, "...");
}
fprintf_filtered (stream, "}");
break;
}
/* Array of unspecified length: treat like pointer. */
valaddr = (char *) &address;
case TYPE_CODE_PTR:
if (format)
{
print_scalar_formatted (valaddr, type, format, 0, stream);
break;
}
fprintf_filtered (stream, "0x%x", * (int *) valaddr);
/* For a pointer to char or unsigned char,
also print the string pointed to, unless pointer is null. */
/* For an array of chars, print with string syntax. */
elttype = TYPE_TARGET_TYPE (type);
if (TYPE_LENGTH (elttype) == 1 && TYPE_CODE (elttype) == TYPE_CODE_INT
&& format == 0
&& unpack_long (type, valaddr) != 0)
{
fputc_filtered (' ', stream);
fputc_filtered ('"', stream);
for (i = 0; i < print_max; i++)
{
QUIT;
read_memory (unpack_long (type, valaddr) + i, &c, 1);
if (c == 0)
break;
printchar (c, stream);
}
fputc_filtered ('"', stream);
if (i == print_max)
fprintf_filtered (stream, "...");
fflush (stream);
/* Return number of characters printed, plus one for the
terminating null if we have "reached the end". */
return i + (print_max && i != print_max);
}
break;
case TYPE_CODE_STRUCT:
case TYPE_CODE_UNION:
fprintf_filtered (stream, "{");
len = TYPE_NFIELDS (type);
for (i = 0; i < len; i++)
{
if (i) fprintf_filtered (stream, ", ");
fprintf_filtered (stream, "%s = ", TYPE_FIELD_NAME (type, i));
if (TYPE_FIELD_PACKED (type, i))
{
val = unpack_field_as_long (type, valaddr, i);
val_print (TYPE_FIELD_TYPE (type, i), &val, 0, stream, format);
}
else
val_print (TYPE_FIELD_TYPE (type, i),
valaddr + TYPE_FIELD_BITPOS (type, i) / 8,
0, stream, format);
}
fprintf_filtered (stream, "}");
break;
case TYPE_CODE_ENUM:
if (format)
{
print_scalar_formatted (valaddr, type, format, 0, stream);
break;
}
len = TYPE_NFIELDS (type);
val = unpack_long (builtin_type_int, valaddr);
for (i = 0; i < len; i++)
{
QUIT;
if (val == TYPE_FIELD_VALUE (type, i))
break;
}
if (i < len)
fprintf_filtered (stream, "%s", TYPE_FIELD_NAME (type, i));
else
fprintf_filtered (stream, "%d", val);
break;
case TYPE_CODE_FUNC:
if (format)
{
print_scalar_formatted (valaddr, type, format, 0, stream);
break;
}
fprintf_filtered (stream, "{");
type_print (type, "", stream, -1);
fprintf_filtered (stream, "} ");
fprintf_filtered (stream, "0x%x", address);
break;
case TYPE_CODE_INT:
if (format)
{
print_scalar_formatted (valaddr, type, format, 0, stream);
break;
}
fprintf_filtered (stream,
TYPE_UNSIGNED (type) ? "%u" : "%d",
unpack_long (type, valaddr));
if (TYPE_LENGTH (type) == 1)
{
fprintf_filtered (stream, " '");
printchar (unpack_long (type, valaddr), stream);
fputc_filtered ('\'', stream);
}
break;
case TYPE_CODE_FLT:
if (format)
{
print_scalar_formatted (valaddr, type, format, 0, stream);
break;
}
#ifdef IEEE_FLOAT
if (is_nan (unpack_double (type, valaddr)))
{
fprintf_filtered (stream, "Nan");
break;
}
#endif
fprintf_filtered (stream, "%g", unpack_double (type, valaddr));
break;
case TYPE_CODE_VOID:
fprintf_filtered (stream, "void");
break;
default: